﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Collections;
using FeatureModel.Collections.TreeArgs;
using EventLogAssembly;

namespace TreeGraphicalControl
{
    public class TreeVersionController
    {
        #region Properties
        public Tree CurrentTree { get { return _curTree; } }
        #endregion

        #region Fields
        protected Stack<Tree> _undoList;
        protected Stack<Tree> _redoList;
        protected Tree _curTree;
        #endregion

        #region Constructor
        /// <summary>
        /// Tree Version Controller
        /// </summary>
        /// <param name="tree"></param>
        public TreeVersionController(Tree tree)
        {
            _undoList = new Stack<Tree>();
            _redoList = new Stack<Tree>();

            _curTree = tree;
            tree.TreeModifyCheck.AddHandler(PushUndo);
            
        }
        #endregion

        /// <summary>
        /// Redo feature model
        /// </summary>
        /// <returns></returns>
        public Tree PopRedo()
        {
            if (_redoList.Count == 0)
            {
                return null;
            }
            // get feature model from redo list
            Tree fm = _redoList.Pop();
            // push current feature model into undo list for further undo
            _undoList.Push(_curTree);
            // switch feature model pop from redo list to current feature model
            _curTree = fm;
            return fm;
        }
        /// <summary>
        /// Peek feature model from redo list
        /// </summary>
        /// <returns></returns>
        public Tree PeekRedo()
        {
            return _redoList.Peek();
        }

        /// <summary>
        /// Push feature model into undo list
        /// </summary>
        /// <param name="fm"></param>
        public void PushUndo(object sender, TreeEventArgs args)
        {
            _undoList.Push((Tree) _curTree .Clone());
        }
        /// <summary>
        /// Undo feature model
        /// </summary>
        /// <returns></returns>
        public Tree PopUndo()
        {
            if (_undoList.Count == 0)
            {
                return null;
            }
            // get feature model from redo list
            Tree fm = _undoList.Pop();
            // push current feature model into undo list for further undo
            _redoList.Push(_curTree);
            // switch feature model pop from redo list to current feature model
            _curTree = fm;
            return fm;
        }
        /// <summary>
        /// Peek feature model from undo list
        /// </summary>
        /// <returns></returns>
        public Tree PeekUndo()
        {
            if (_undoList.Count == 0)
            {
                return null;
            }
            return _undoList.Peek();
        }

    }
}
